/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using System.Threading.Tasks;
using System;

namespace NetProtocol.Server {
	/// <summary>
	/// 编队
	/// module : formation
	/// </summary>
	public interface SNetFormation : INetServerModule {
		Dictionary<int, MessageHandler> INetServerModule.GetModuleFunction()
        {	
            return new()
            {
                { NetMessageId.formation_setCaptain, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.formation_setCaptain, "Recv->" + data.ToString());
#endif
		                SetCaptainRequest _data = (SetCaptainRequest)data;
						return CS_setCaptain(session, _data.formId, _data.heroCid);
		            } 
            	},
                { NetMessageId.formation_setHero, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.formation_setHero, "Recv->" + data.ToString());
#endif
		                SetHeroRequest _data = (SetHeroRequest)data;
						return CS_setHero(session, _data.formId, _data.pos, _data.heroCid);
		            } 
            	},
                { NetMessageId.formation_setFormName, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.formation_setFormName, "Recv->" + data.ToString());
#endif
		                SetFormNameRequest _data = (SetFormNameRequest)data;
						return CS_setFormName(session, _data.formId, _data.name);
		            } 
            	},
                { NetMessageId.formation_setDefault, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.formation_setDefault, "Recv->" + data.ToString());
#endif
		                SetDefaultRequest _data = (SetDefaultRequest)data;
						return CS_setDefault(session, _data.formId);
		            } 
            	},
            };
        }
        
        Dictionary<int, Func<IReceiveMessage>> INetServerModule.GetModuleRequest() 
        {
	        return new ()
	        {
	        	{NetMessageId.formation_setCaptain, ()=> new SetCaptainRequest()},
	        	{NetMessageId.formation_setHero, ()=> new SetHeroRequest()},
	        	{NetMessageId.formation_setFormName, ()=> new SetFormNameRequest()},
	        	{NetMessageId.formation_setDefault, ()=> new SetDefaultRequest()},
	        };
	    }
        
#region Server-side Interface
		/// <summary>
        ///  设置队长
        /// </summary>
	    protected SetCaptainResult CS_setCaptain(ISession session, int formId, int heroCid);
		/// <summary>
        ///  设置英雄 -- heroCid为0表示下阵
        /// </summary>
	    protected SetHeroResult CS_setHero(ISession session, int formId, int pos, int heroCid);
		/// <summary>
        ///  设置编队名
        /// </summary>
	    protected SetFormNameResult CS_setFormName(ISession session, int formId, string name);
		/// <summary>
        ///  设置默认编队
        /// </summary>
	    protected SetDefaultResult CS_setDefault(ISession session, int formId);
#endregion
#region Client-side Interface
		/// <summary>
        ///  更新编队，客户端只在这里更新数据，其它协议仅做展示；先更新数据，再通知结果
        /// </summary>
		public bool SC_notifyFormation(ISession session, FormationPOD formationPOD){
	        return NetProtocolHelper.SendMessage(session, new NotifyFormation(formationPOD));
	    }
	    public void SC_notifyFormation_Broadcast(List<ISession> sessions, FormationPOD formationPOD){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyFormation(formationPOD));
	    }
		/// <summary>
        ///  设置队长结果
        /// </summary>
        public SetCaptainResult SC_setCaptainResult(Task<SetCaptainResult> future){return new SetCaptainResult(future);}
        public SetCaptainResult SC_setCaptainResult(int code){return new SetCaptainResult(code);}
		/// <summary>
        ///  设置英雄结果
        /// </summary>
        public SetHeroResult SC_setHeroResult(Task<SetHeroResult> future){return new SetHeroResult(future);}
        public SetHeroResult SC_setHeroResult(int code){return new SetHeroResult(code);}
		/// <summary>
        ///  设置编队名结果
        /// </summary>
        public SetFormNameResult SC_setFormNameResult(Task<SetFormNameResult> future){return new SetFormNameResult(future);}
        public SetFormNameResult SC_setFormNameResult(int code){return new SetFormNameResult(code);}
		/// <summary>
        ///  设置默认编队，成功时更新本地数据
        /// </summary>
        public SetDefaultResult SC_setDefaultResult(Task<SetDefaultResult> future){return new SetDefaultResult(future);}
        public SetDefaultResult SC_setDefaultResult(int code, int formId){return new SetDefaultResult(code, formId);}
        public SetDefaultResult SC_setDefaultResult(int code){return new SetDefaultResult(code);}
#endregion

#region Messages
	public class NotifyFormation : MessageNotify {
		private FormationPOD formationPOD;
		public NotifyFormation(FormationPOD formationPOD) {
		    this.formationPOD = formationPOD;
		}
		public override int GetMessageId() {return NetMessageId.formation_notifyFormation;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_notifyFormation;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(formationPOD);
			return si_p;
		}
		public override string ToString() {
			return "Formation.SC_notifyFormation { "
			+ "formationPOD="
			+ formationPOD
			+" }";
		}
	}
	public class SetCaptainResult : MessageResult {
	    public SetCaptainResult(Task<SetCaptainResult> future): base(future) { }
		public SetCaptainResult(int code): base(code) { }
		public new SetCaptainResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<SetCaptainResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.formation_setCaptainResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setCaptainResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Formation.SC_setCaptainResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class SetHeroResult : MessageResult {
	    public SetHeroResult(Task<SetHeroResult> future): base(future) { }
		public SetHeroResult(int code): base(code) { }
		public new SetHeroResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<SetHeroResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.formation_setHeroResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setHeroResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Formation.SC_setHeroResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class SetFormNameResult : MessageResult {
	    public SetFormNameResult(Task<SetFormNameResult> future): base(future) { }
		public SetFormNameResult(int code): base(code) { }
		public new SetFormNameResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
        public override MessageResult GetFutureResult(Task task) { return ((Task<SetFormNameResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.formation_setFormNameResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setFormNameResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			return si_p;
		}
		public override string ToString() {
    		return "Formation.SC_setFormNameResult { "
			+ "code="
			+ code
			+" }";
		}
	}
	public class SetDefaultResult : MessageResult {
	    private int formId;
	    public SetDefaultResult(Task<SetDefaultResult> future): base(future) { }
		public SetDefaultResult(int code): base(code) { }
		public new SetDefaultResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal SetDefaultResult(int code, int formId){
	        this.code = code;
	        this.formId = formId;
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<SetDefaultResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.formation_setDefaultResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.formation_setDefaultResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_int(formId);
			return si_p;
		}
		public override string ToString() {
    		return "Formation.SC_setDefaultResult { "
			+ "code="
			+ code
			+ ", formId="
			+ formId
			+" }";
		}
	}
	private class SetCaptainRequest : IReceiveMessage
    {
		internal int formId;
		internal int heroCid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            formId = _in.HasRemaining() ? _in.Read_int() : default;
            heroCid = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.formation_setCaptain; }
        public override string ToString()
        {
            return "Formation.setCaptain"+ ", formId="+ formId+ ", heroCid="+ heroCid;
        }
    }
	private class SetHeroRequest : IReceiveMessage
    {
		internal int formId;
		internal int pos;
		internal int heroCid;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            formId = _in.HasRemaining() ? _in.Read_int() : default;
            pos = _in.HasRemaining() ? _in.Read_int() : default;
            heroCid = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.formation_setHero; }
        public override string ToString()
        {
            return "Formation.setHero"+ ", formId="+ formId+ ", pos="+ pos+ ", heroCid="+ heroCid;
        }
    }
	private class SetFormNameRequest : IReceiveMessage
    {
		internal int formId;
		internal string name;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            formId = _in.HasRemaining() ? _in.Read_int() : default;
            name = _in.HasRemaining() ? _in.Read_string() : default;
		}
        public int GetMessageId() { return NetMessageId.formation_setFormName; }
        public override string ToString()
        {
            return "Formation.setFormName"+ ", formId="+ formId+ ", name="+ name;
        }
    }
	private class SetDefaultRequest : IReceiveMessage
    {
		internal int formId;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            formId = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.formation_setDefault; }
        public override string ToString()
        {
            return "Formation.setDefault"+ ", formId="+ formId;
        }
    }
	}
#endregion
}